package com.kgc.sbt.provider111;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.kgc.sbt.api.UserApi;
import com.kgc.sbt.beans.*;
import com.kgc.sbt.config.WechatAuthConfig;
import com.kgc.sbt.mapper.FootprintMapper;
import com.kgc.sbt.mapper.SignMapper;
import com.kgc.sbt.mapper.UserLoginMapper;
import com.kgc.sbt.mapper.VipMapper;
import com.kgc.sbt.utils.RedisUtils;
import com.kgc.sbt.utils.RequestResult;
import com.kgc.sbt.utils.ResultBuildUtil;
import com.kgc.sbt.utils.Sample;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;


import java.net.PasswordAuthentication;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created on 2021/8/19.
 * <p>
 * Author: 190120
 * <p>
 * Description:
 */
@Service
@Slf4j
public class UserProvider implements UserApi {

    @Autowired
    private FootprintMapper footprintMapper;
    @Autowired
    private UserLoginMapper userLoginMapper;

    @Autowired
    private SignMapper signMapper;
    @Autowired
    private UserProvider userProvider;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private WechatAuthConfig wechatAuthConfig;
    @Autowired
    private UserApi userApi;

    @Autowired
    private VipMapper vipMapper;

    /**
     * @return
     * @author 190120
     * @date 2021/6/21
     * @descrption： 发送短信
     */
    @Override
    public RequestResult<Map<String, Object>> sendCode(String phone) {
        Map<String, Object> data = new HashMap<>();
        Random random = new Random();
        int code = random.nextInt(10000);
        while (code < 1000) {
            code = random.nextInt(10000);
        }
        Sample.smsSign(phone, code);
        //将验证码存入redis
        data.put("phone", phone);
        data.put("code", code);
        if (redisUtils.set(phone, code, 600)) {
            data.put("msg", "验证码发送成功！");
        } else {
            log.info("------ 根据手机号{},验证码过期，重新生成存入redis失败 ------", phone);
            return ResultBuildUtil.fail("3001", "验证码获取失败");
        }
        // 判断操作是否合法（10s内最多3次）
        if (!redisUtils.checkFreq("sendSMS:" + phone, 3, 10)) {
            return ResultBuildUtil.fail("3001", "发送过于频繁,请稍后再试");
        }
        if (redisUtils.hasKey(phone)) {
            log.info("------手机号{},验证码没有过期 ------", phone);
            return ResultBuildUtil.success(data);
        }
        return ResultBuildUtil.success(data);
    }


    @Override
    public UserLogin querByPhone(String phone) {

        UserLoginExample userLoginExample = new UserLoginExample();
        UserLoginExample.Criteria criteria = userLoginExample.createCriteria();
        criteria.andUserPhoneEqualTo(phone);

        try {
            return userLoginMapper.selectByExample(userLoginExample).get(0);
        } catch (Exception e) {
            return null;
        }
//        return userLoginMapper.selectByPhone(phone);
    }

    @Override
    public void insertUser(String phone, String password, String userName) {
        UserLogin userLogin = new UserLogin();
        userLogin.setUserName(userName);
        userLogin.setUserPassword(password);
        userLogin.setUserPhone(phone);
        userLoginMapper.insertSelective(userLogin);
    }

    @Override
    public UserLogin queryUserEntryById(Integer userId) {
        return userLoginMapper.selectByPrimaryKey(userId);
//        return userLoginMapper.selectUserById(userId);
    }

    @Override
    public boolean updatePasswordById(Integer userId, String password) {
        /*UserLogin userLogin = new UserLogin();
        userLogin.setUserId(userId);
        userLogin.setUserPassword(password);*/
//        return userLoginMapper.updatePasswordById(userId, password);

        UserLogin userLogin = userLoginMapper.selectByPrimaryKey(userId);
        userLogin.setUserPassword(password);
        return userLoginMapper.updateByPrimaryKey(userLogin) > 0;

    }

    @Override
    public boolean updatePhoneById(Integer userId, String newPhone) {
//        return userLoginMapper.updatePhoneById(userId, newPhone);
        UserLogin userLogin = userLoginMapper.selectByPrimaryKey(userId);
        userLogin.setUserPhone(newPhone);
        return userLoginMapper.updateByPrimaryKey(userLogin) > 0;
    }

    @Override
    public boolean updateUserNameById(Integer userId, String newName) {
//        return userLoginMapper.updateUserNameById(userId, newName);
        UserLogin userLogin = userLoginMapper.selectByPrimaryKey(userId);
        userLogin.setUserName(newName);
        return userLoginMapper.updateByPrimaryKey(userLogin) > 0;
    }

    @Override
    public Integer userSigned(Integer userId) {
        // 声明旗帜对象
        Boolean flag = false;

        // 声明时间格式化对象
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        // 声明时间对象
        Date date = new Date();
        // 声明现在时间对象
        Calendar now = Calendar.getInstance();
        // 赋予时间对象现在的时间时间
        now.setTime(date);

        // 格式化今天时间对象
        String today = sdf.format(now.getTime());

        // 当前时间-1天
        now.add(Calendar.DAY_OF_MONTH, -1);

        // previous前1天格式化时间，字符串
        String previous = sdf.format(now.getTime());

        // 获取签到实体
        Sign sign1 = signMapper.selectSignByUserId(userId);
        // 空校验,判断是否首次签到
        if (sign1 != null && !"".equals(sign1)) {
            flag = true;
        }

        // 判断是否后续签到
        if (flag) {

            // 获取用户签到表
            SignExample signExample = new SignExample();
            signExample.setDistinct(false);
            signExample.setOrderByClause("user_id desc");
            SignExample.Criteria criteria = signExample.createCriteria();
            criteria.andUserIdEqualTo(userId);
            List<Sign> signList = signMapper.selectByExample(signExample);
            Sign sign = new Sign();
            for (Sign sign2 : signList) {
                sign = sign2;
            }

            // date2是上次更新时间
            Date date2 = sign.getUpdateTime();
            // 看不懂
            Calendar last = Calendar.getInstance();
            // last是上次更新时间
            last.setTime(date2);
            // lastSign是上次更新时间
            String lastSign = sdf.format(last.getTime());


            log.info("previous:{},lastSign:{}", previous, lastSign);
            // 判断1天前和上次更新时间是否相等(精确到天)
            if (previous.equals(lastSign)) {
                // 实体属性双+1
                Integer conSign = sign.getContinueSign() + 1;
                sign.setContinueSign(conSign);
                sign.setCount(sign.getCount() + 1);

                // 判断现在时间和上次更新时间是否相等（精确到天）
            } else if (today.equals(lastSign)) {
                return 2;
            } else {
                sign.setContinueSign(1);
                sign.setCount(sign.getCount() + 1);
            }
            // 判断是否签了第7天
            if (sign.getContinueSign() == 7) {
                addPoints(userId, 20);
                sign.setContinueSign(0);
            }

            // 设置实体属性并更新表，正常返回1，错误返回ec
            sign.setUserId(userId);
            sign.setUpdateTime(date);
            if (signMapper.updateByPrimaryKey(sign) > 0) {
                return 1;
            } else {
                return 0;
            }

            //首次签到初始化，并返回1，错误返回3
        } else {
            // 声明新的签到实体，设置值
            Sign sign = new Sign();
            sign.setUserId(userId);
            sign.setCount(1);
            sign.setContinueSign(1);
            sign.setCreateTime(date);
            sign.setUpdateTime(date);

            //判断插入是否成功
            if (signMapper.insert(sign) > 0) {
                return 1;
            } else {
                return 3;
            }
        }


    }

    @Override
    public Sign querySignByUserId(Integer userId) {
        return signMapper.selectSignByUserId(userId);
    }

    @Override
    public Boolean addPoints(Integer userId, Integer points) {
        UserLogin user = userLoginMapper.selectByPrimaryKey(userId);
        user.setIntegral(user.getIntegral() + points);
        if (userLoginMapper.updateByPrimaryKeySelective(user) > 0) {
            return true;
        }
        return false;
    }

    @Override
    public UserLogin queryUserByUserId(Integer userId) {
        return userLoginMapper.selectByPrimaryKey(userId);
    }

    @Override
    public UserLogin queryByOpenId(String openId) {

        UserLoginExample userLoginExample = new UserLoginExample();
        UserLoginExample.Criteria criteria = userLoginExample.createCriteria();
        criteria.andOpenIdEqualTo(openId);

        try {
            return userLoginMapper.selectByExample(userLoginExample).get(0);
        } catch (Exception e) {
            return null;
        }
//        return userLoginMapper.selectByOpenid(openId);
    }

    @Override
    public boolean updateUserByPhone(String phoneNo, String openId) {
//        return userLoginMapper.updateUserByPhone(phoneNo, openId);

        UserLoginExample userLoginExample = new UserLoginExample();
        UserLoginExample.Criteria criteria = userLoginExample.createCriteria();
        criteria.andUserPhoneEqualTo(phoneNo);

        UserLogin userLogin = userLoginMapper.selectByExample(userLoginExample).get(0);
        userLogin.setOpenId(openId);

        return userLoginMapper.updateByPrimaryKey(userLogin) > 0;
    }

    @Override
    public void saveToken(String token, Integer userId) {
        UserLogin userLogin = userLoginMapper.selectByPrimaryKey(userId);
        userLogin.setToken(token);
        userLoginMapper.updateByPrimaryKey(userLogin);
    }

    @Override
    public void delToken(String token) {
        UserLoginExample userLoginExample = new UserLoginExample();
        UserLoginExample.Criteria criteria = userLoginExample.createCriteria();
        criteria.andTokenEqualTo(token);
        UserLogin userLogin = userLoginMapper.selectByExample(userLoginExample).get(0);
        userLogin.setToken("");
        userLoginMapper.updateByPrimaryKey(userLogin);
    }

    @Override
    public Boolean queryVipByUserId(Integer userId) {
        return ObjectUtils.isEmpty(vipMapper.selectByPrimaryKey(userId));
    }

    @Override
    public void insertVipByUserId(Integer userId) {
        vipMapper.insetUserId(userId);
    }
}
